<!--
 * @Description:地图
                    modularHide: 左右抽屉
 * @Version: 2.0
 * @Author: zhao
 * @Date: 2022-06-15 09:21:53
 * @LastEditors: zhao
 * @LastEditTime: 2022-07-05 16:41:18
-->
<template>
    <div id="mapCon">
        <!-- <buttonGroup v-if="modularHide" /> -->
        <zdrawer v-if="modularHide" :drawer_config="{ direction: 'left', open: true, right_open: right_open }" />
        <!-- <zdrawer v-if="modularHide" :butmap="map" :drawer_config="{ direction: 'right' }" /> -->
        <dataDetails :map="map" :markerLayer="markerLayer" />
    </div>
</template>

<script>
import zdrawer from "./compoments/drawer.vue"
import dataDetails from "./dataDetails.vue"
import "ol/ol.css"
import Map from "ol/Map"
import View from "ol/View"
import TileLayer from "ol/layer/Tile"
import XYZ from "ol/source/XYZ"
// import OSM from 'ol/source/OSM' // 可以理解为数据源,就是一张图片

import { Vector as SourceVec, Cluster } from "ol/source"
import { defaults } from "ol/interaction"

import { Vector as VectorLayer } from "ol/layer" // 实例化一个矢量图层Vector作为绘制层

import { Feature } from "ol"
import { Style, Icon, Fill, Stroke, Text, Circle as CircleStyle } from "ol/style"
import GeoJSON from "ol/format/GeoJSON"
import { Vector as VectorSource, TileJSON } from "ol/source"
import { LinearRing, Point, Polygon, Circle as geomCircle } from "ol/geom" // 点线面
import { fromCircle, fromExtent } from "ol/geom/Polygon" //
import { fromLonLat, toLonLat } from "ol/proj"
import img from "@/assets/zuobiao_red.png"
import OSM from "ol/source/OSM"
import { OverviewMap, defaults as defaultControls } from "ol/control"
import China from "@/assets/100000.json"
import { getVectorContext } from "ol/render"
import * as olProj from "ol/proj"
import { buffer } from "ol/extent"
export default {
    components: {
        zdrawer,
        dataDetails,
    },
    props: {
        modularHide: {
            type: Boolean,
            default: false,
        },
        MapParameter: {
            type: Object,
            default: () => {
                return {
                    center: [116.394926, 39.9125],
                    zoom: 7,
                    mapPoint: [],
                }
            },
        },
    },
    data() {
        return {
            map: null,
            tiandiMap: null,
            vectorSource: null, // 边界绘制
            draw: null, // 绘制图形
            markerLayer: null, //坐标图层 点坐标
            sourceArr: null, //标注点
            MapView: {}, //地图视图设置
            GeoJSONLayer: null, //几何图形 图层
            right_open: false,
            tk: "579cbafd290f72fb69ef5319e2bd149c",
        }
    },
    created() {
        // this.$store.state.map.mapList = []
    },
    activated() {
        // this.init()
    },
    mounted() {
        this.init()
        this.$store.state.map.mapData = this.MapParameter
    },
    watch: {
        "$store.state.map.mapList": {
            handler: function (val, oldVal) {
                this.addMarker()
                this.$store.state.map.overlayForm && this.$store.state.map.overlayForm.setPosition(undefined)

                let data = this.$store.state.map.form

                if (this.$store.state.map.selectType == "first") {
                    if (data.area && data.area.area_number) return this.setBoundaryDraw(data.area.area_number)
                    if (data.city && data.city.area_number) return this.setBoundaryDraw(data.city.area_number)
                    if (data.province && data.province.area_number) return this.setBoundaryDraw(data.province.area_number)
                }
                const pageType = this.$store.state.map.pageType
                if (pageType == "SpatialRetrieval") {
                    if (data.area && data.area.area_number) return this.setBoundaryDraw(data.area.area_number)
                    if (data.city && data.city.area_number) return this.setBoundaryDraw(data.city.area_number)
                    if (data.province && data.province.area_number) return this.setBoundaryDraw(data.province.area_number)
                    // this.invertQueryData()
                    this.$store.state.map.pageType = ""
                }
            },
            immediate: true,
            deep: true,
        },

        "$store.state.map.mapData": {
            handler: function (val, oldVal) {
                this.map &&
                    this.map.setView(
                        new View({
                            center: val.center, //设置中心点
                            zoom: val.zoom, //设置级别
                            projection: "EPSG:4326",
                            maxZoom: 14,
                            minZoom: 6,
                        })
                    )
                // this.map.changed()
            },
            immediate: true,
            deep: true,
        },
        "$store.state.map.form": {
            handler: function (data, oldVal) {
                if (this.$store.state.map.selectType != "first") {
                    if (data.area && data.area.area_number) return this.setBoundaryDraw(data.area.area_number)
                    if (data.city && data.city.area_number) return this.setBoundaryDraw(data.city.area_number)
                    if (data.province && data.province.area_number) return this.setBoundaryDraw(data.province.area_number)
                }
                // this.map.changed()
            },
            immediate: true,
            deep: true,
        },
    },

    methods: {
        init() {
            // this.mapPoint = this.MapParameter.mapPoint
            this.$store.state.map.map = this.map = new Map({
                // controls: defaultControls().extend([overviewMapControl]),
                target: "mapCon",
                layers: [
                    // new TileLayer({
                    //     source: source,
                    // }),
                    new TileLayer({
                        source: new XYZ({
                            url: "http://t3.tianditu.com/DataServer?T=vec_w&x={x}&y={y}&l={z}&tk=" + this.$store.state.map.tk,
                            crossOrigin: "anonymous",
                            opaque: "true",
                        }),
                    }),
                    // new TileLayer({
                    //     source: new ol.source.TileJSON({
                    //         url: 'https://api.tiles.mapbox.com/v4/mapbox.geography-class.json?secure&access_token=pk.eyJ1IjoiYWhvY2V2YXIiLCJhIjoiY2pzbmg0Nmk5MGF5NzQzbzRnbDNoeHJrbiJ9.7_-_gL8ur7ZtEiNwRfCy7Q',
                    //         crossOrigin: 'anonymous'
                    //     })
                    // }),
                    new TileLayer({
                        source: new XYZ({
                            // url: "https://{a-c}.tile.openstreetmap.org/{z}/{x}/{y}.png", // 天地图
                            url: "http://t3.tianditu.com/DataServer?T=cva_w&x={x}&y={y}&l={z}&tk=" + this.$store.state.map.tk,
                            crossOrigin: "anonymous",
                        }),
                    }),
                ],
                // view: new View({
                //     source: new ol.source.Vector({
                //         //url: './data/Line.json',     // 地图来源 使用本地url 离线加载会报跨域问题
                //         url: 'https://geo.datav.aliyun.com/areas_v3/bound/130000_full.json',     // 地图来源
                //         format: new GeoJSON()    // 解析矢量地图的格式化类
                //     })

                // }),
                view: new View({
                    center: this.$store.state.map.mapData.center,
                    projection: "EPSG:4326",
                    zoom: this.$store.state.map.mapData.zoom,
                }),
                interactions: new defaults({
                    doubleClickZoom: false, //屏蔽双击放大事件
                }),
            })

            this.addMarker()
            this.setBoundaryDraw("130000")
        },
        // 生成点坐标
        addvectorSource() {},
        // 添加标注+聚合
        addMarker() {
            // 创建画板
            // this.markerLayer && this.map.removeLayer(this.markerLayer)

            this.delMarker()
            // this.markerLayer && this.map.removeLayer(this.markerLayer)
            let sourceArr = new SourceVec({})

            this.$store.state.map.mapList.forEach((e) => {
                const feature = new Feature({
                    geometry: new Point(e.LonLat),
                    name: e.id,
                })
                const markerStyle = new Style({
                    image: new Icon({
                        opacity: 1,
                        src: img,
                        scale: "1", // 图片缩放比例
                    }),
                })
                feature.setStyle(markerStyle)
                feature.set("LonLat", e.LonLat)
                feature.set("Title", e.title)
                feature.set("Author", e.author)
                feature.set("Company", e.company)
                feature.set("Reference", e.reference)
                feature.set("Abstract", e.abstract)

                feature.set("Category", e.category)
                feature.set("District", e.district)
                feature.set("FormDate", e.formDate)
                feature.set("FormInstitution", e.formInstitution)
                feature.set("WorkArea", e.workArea)

                feature.set("workAreaMaxX", e.workAreaMaxX)
                feature.set("workAreaMaxY", e.workAreaMaxY)
                feature.set("workAreaMinX", e.workAreaMinX)
                feature.set("workAreaMinY", e.workAreaMinY)

                feature.set("maxX", e.maxX)
                feature.set("maxY", e.maxY)
                feature.set("minX", e.minX)
                feature.set("minY", e.minY)

                feature.set("sn", e.sn)

                sourceArr.addFeature(feature)
            })

            //矢量标注图层
            this.markerLayer = new VectorLayer({
                zIndex: 100,
                source: sourceArr,
            })

            // // 聚合
            // var cluster = new Cluster({
            //     source: sourceArr,
            //     distance: 0,
            // })
            // // 添加进map层-聚合点-LayerVec /VectorLayer  这两种都可以
            // this.markerLayer = new VectorLayer({
            //     zIndex: 100,
            //     source: cluster,
            //     style: function (feature, resolution) {
            //         var size = feature.get("features").length
            //         // 如果是聚合数为1也就是最底层的则是定位图标
            //         if (size === 1) {
            //             return new Style({
            //                 image: new Icon({
            //                     anchor: [0.5, 1],
            //                     src: img,
            //                 }),
            //             })
            //         } else {
            //             // 这里设置聚合部分的样式
            //             return new Style({
            //                 image: new CircleStyle({
            //                     radius: 10,
            //                     stroke: new Stroke({
            //                         color: "#fff",
            //                     }),
            //                     fill: new Fill({
            //                         color: "rgb(243, 126, 126)",
            //                     }),
            //                 }),
            //                 text: new Text({
            //                     text: size.toString(),
            //                     fill: new Fill({
            //                         color: "#fff",
            //                     }),
            //                 }),
            //             })
            //         }
            //     },
            // })

            // 地图添加画板
            this.map && this.map.addLayer(this.markerLayer)

            // this.$store.state.map.SourceVec = sourceArr
            this.$store.commit("map/setStorage_SourceVec", sourceArr)
            this.$store.state.map.markerLayer = this.markerLayer
        },
        // 删除边界绘制
        delMarker() {
            if (this.vectorSource != null) {
                this.vectorSource.clear()
            }

            this.markerLayer && this.map.removeLayer(this.markerLayer)
        },
        // 地区边界绘制
        async setBoundaryDraw(code) {
            this.$store.commit("map/empty")

            const features = new GeoJSON({ featureProjection: "EPSG:4326" }).readFeatures(this.geojson(code))
            this.$store.state.map.boundaryLayer = new VectorSource({ features: features })

            this.$store.state.map.GeoJSONLayer = new VectorLayer({
                zIndex: 99,
                source: this.$store.state.map.boundaryLayer,
                style: new Style({
                    // fill: new Fill({ color: "#4e98f444" }),
                    // fill: new Fill({ color: "#afdfe4" }),
                    stroke: new Stroke({
                        width: 3,
                        color: [71, 137, 227, 1],
                    }),
                }),
            })

            this.map && this.map.addLayer(this.$store.state.map.GeoJSONLayer) // 把图层添加到地图
        },
        //结果列划上 高亮相应点
        mouseenterMapData(data) {
            // console.log("🚀 ~ file: index.vue ~ line 415 ~ mouseenterMapData ~ data", data)
        },
        //获取geojosn
        geojson(code) {
            let json = require("@/assets/json/" + code + ".json")
            if (code == "130000" || code == "130000_full") {
                this.$store.state.map.mapData.center = [116.394926, 39.9125]
            } else {
                this.$store.state.map.mapData.center = json.features[0].properties.center
            }
            return json
        },
        heightLight(points, ctx) {
            let data = require("@/assets/json/130000.json")
            var fts = new GeoJSON().readFeatures(data)
            var ft = fts[0]
            var converGeom = ft.getGeometry()
            // converGeom.applyTransform(ol.proj.getTransform('EPSG:4326', 'EPSG:3857'));
            //var convertFt =new  ol.Feature(converGeom);
            //converLayer.getSource().addFeature(convertFt);
            var center, pixelScale, offsetX, offsetY, rotation
            this.map.on("precompose", (evt) => {
                var canvas = evt.context
                canvas.save()

                var coords = converGeom.getCoordinates()
                var frameState = evt.frameState
                var pixelRatio = frameState.pixelRatio
                var viewState = frameState.viewState
                center = viewState.center
                var resolution = viewState.resolution
                rotation = viewState.rotation
                var size = frameState.size
                var size1 = this.map.getSize()
                offsetX = Math.round((pixelRatio * size[0]) / 2)
                offsetY = Math.round((pixelRatio * size[1]) / 2)
                pixelScale = pixelRatio / resolution

                canvas.beginPath()
                if (converGeom.getType() == "MultiPolygon") {
                    for (var i = 0; i < coords.length; i++) {
                        createClip(coords[i][0], canvas)
                    }
                } else if (converGeom.getType() == "Polygon") {
                    createClip(coords[0], canvas)
                }
                canvas.backgroundColor = "black"
                canvas.clip()
            })

            function createClip(coords, canvas) {
                for (var i = 0, cout = coords.length; i < cout; i++) {
                    var xLen = Math.round((coords[i][0] - center[0]) * pixelScale)
                    var yLen = Math.round((center[1] - coords[i][1]) * pixelScale)
                    var x = offsetX
                    var y = offsetY
                    if (rotation) {
                        x = xLen * Math.cos(rotation) - yLen * Math.sin(rotation) + offsetX
                        y = xLen * Math.sin(rotation) + yLen * Math.cos(rotation) + offsetY
                    } else {
                        x = xLen + offsetX
                        y = yLen + offsetY
                    }
                    if (i == 0) {
                        canvas.moveTo(x, y)
                    } else {
                        canvas.lineTo(x, y)
                    }
                }
                canvas.closePath()
            }

            this.map.on("postcompose", function (event) {
                var ctx = event.context
                ctx.restore()
            })
        },
        //创建蒙层，
        showGuangxiArea() {
            let initLayer = new VectorLayer({
                zIndex: 3,
                source: new VectorSource(),
                style: new Style({
                    fill: new Fill({
                        color: "rgba( 255, 255, 255, 0.7)",
                    }),
                    stroke: new Stroke({
                        color: "#f4b49f",
                        width: 3,
                    }),
                }),
            })
            this.map.addLayer(initLayer)
            let data = require("@/assets/json/130000.json")
            this.addConver(initLayer, data)
        },
        //添加遮罩
        addConver(converLayer, data) {
            const fts = new GeoJSON().readFeatures(data)
            const ft = fts[0]
            const converGeom = this.erase(ft.getGeometry())
            const convertFt = new Feature({
                geometry: converGeom,
            })
            converLayer.getSource().addFeature(convertFt)
        },
        //擦除操作，生产遮罩范围
        erase(geom) {
            const extent = [-180, -90, 180, 90]
            const polygonRing = fromExtent(extent)
            const coords = geom.getCoordinates()
            coords.forEach((coord) => {
                const linearRing = new LinearRing(coord[0])
                polygonRing.appendLinearRing(linearRing)
            })
            return polygonRing
        },
    },
}
</script>

<style scoped lang="scss">
#mapCon {
    width: 100%;
    height: 100%;
    // color: ;
    position: relative !important;
    overflow: hidden;
}
</style>
